package com.baidu.automata.core.flow;

import java.util.HashMap;
import java.util.Map;

import org.apache.log4j.Logger;

import com.baidu.automata.core.context.Context;
import com.baidu.automata.core.type.DataField;

public class BaseOperation {
	private final static Logger logger = Logger.getLogger("flow_Platform");
	
	protected String id = null;

	protected Context ctx = null;

	protected Map<String, BaseOpStep> opSteps = new HashMap<String, BaseOpStep>();

	public BaseOperation() {
		super();
	}

	public BaseOperation(String id) {
		super();
		this.id = id;
	}

	public Context getCtx() {
		return ctx;
	}

	public void setCtx(Context ctx) {
		this.ctx = ctx;
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public void addDataField(DataField f) {
		this.ctx.addDataField(f);
	}

	public DataField getDataFieldById(String id) {
		return this.ctx.getDataFieldById(id);
	}

	public DataField removeDataFieldById(String id) {
		return this.ctx.removeDataFieldById(id);
	}

	public void addOpStep(BaseOpStep step) {
		this.opSteps.put(step.getId(), step);
	}

	public final int execute() throws Exception {
		for(BaseOpStep step :opSteps.values()) {
			step.setCtx(this.ctx);
		}
		
		logger.info(String.format("operation [%s] is starting...", this.id));
		
		String runningOpStepId = "start";

		BaseOpStep runningOpStep = this.opSteps.get(runningOpStepId);

		while (true) {
			if (runningOpStep == null) {
				logger.error(String.format("step [%s] not exist", runningOpStepId));
				throw new Exception(String.format("step [%s] not exist", runningOpStepId));
			}

			logger.info(String.format("step [%s] is starting...", runningOpStepId));
			
			int exitCode = runningOpStep.execute();

			logger.info(String.format("step [%s] finished, exit code is %s", runningOpStepId, exitCode));
			
			runningOpStepId = runningOpStep.getForwardOpStepId(exitCode);
			if ("end".endsWith(runningOpStepId)) {
				break;
			}

			runningOpStep = this.opSteps.get(runningOpStepId);
		}
		
		logger.info(String.format("operation [%s] finished", this.id));
		
		return 0;
	}
}
